require 'fusefs'
require 'drb'

module Mil
  module FS
      class FuseDir < FuseFS::FuseDir
	def initialize(index_drb, store_drb)
	  @store = store_drb
	  @index = index_drb
	end

	# 
	# Begin Fuse Methods
	#
	def contents(path)
	  namespace, query = scan_path(path)
	  contents = []

	  if namespace
	    str = "namespace:#{namespace}"
	    str += " AND #{query}" if query

	    docs = @index.query(str)

	    unless docs.empty?
	      for i in (0..docs.size - 1)
		contents << docs[i][:document].value(0)
	      end
	    end

	  else
	    contents = @index.namespaces

	    unless contents.nil? or ! contents.is_a? Array
	      contents = [ 'global' ]
	    end

	  end

	  contents
	end

	def directory?(path)
	  namespace, query = scan_path(path)

	  if query
	    false
	  elsif namespace == "global"
	    true
	  else
	   @index.is_namespace? namespace
	  end
	end

	def file?(path)
	  namespace, query = scan_path(path)

	  # Possible to create a
	  # grammar that allows for options to be passed such as
	  # the size of list to return.

	  if query
	    # Since list returns an array of all matches, just check
	    # that the array is not empty.
	    result = @index.query("namespace:#{namespace} AND #{query}")

	    if result and ! result.empty?
	      true
	    else
	      false
	    end
	  else
	    if namespace == "global"
	      true
	    else
	      @index.is_namespace? namespace
	    end
	  end
	end

	def touch(path)
	  puts "#{path} has been pushed like a button!"
	end

	# File reading
	def read_file(path)
	  namespace, query = scan_path(path)

	  # For now, return the contents of the first file that matches the query.
	  addr = @index.query("namespace:#{namespace} AND #{query}", 1)[0][:document].data

	  puts "fetching #{addr}"
	  file = @store.retrieve(addr)

	  puts "got #{file.name}"
	  file.contents
	end

	# File writing
	def can_write?(path)
	  begin
	    namespace, query = scan_path(path)

	    if namespace == "global" or @index.is_namespace? namespace
	      true
	    else
	      false
	    end
	  rescue Exception => er
	    puts "Error in can_write? : #{er}\n#{er.backtrace}"
	    
	    false
	  end
	end

	def write_to(path,body)
	  begin
	    namespace, name = scan_path(path)

	    puts "Writing file #{name} in namespace #{namespace}"
	    file = Mil::FS::File.new( :namespaces => [ namespace ], :name => name, :contents => body )
	    @index.index( @store.store(file) )
	  rescue Exception => er
	    puts "Error in write_to : #{er}\n#{er.backtrace}"
	  end
	end

	# Delete a file
	def can_delete?(path)
	  namespace, query = scan_path(path)

	  true
	end
	def delete(path)
	  namespace, query = scan_path(path)

	  # For now, return the contents of the first file that matches the query.
	  file = @index.query("namespace:#{namespace} AND #{query}", 1)[0]

	  @store.delete(file[:document].data)
	end

	# mkdirs
	def can_mkdir?(path)
	  namespace, query = scan_path(path)

	  true
	end
	def mkdir(path)
	  namespace, query = scan_path(path)

	  true
	end

	# rmdir
	def can_rmdir?(path)
	  namespace, query = scan_path(path)

	  true
	end
	def rmdir(path)
	  namespace, query = scan_path(path)

	  true
	end
      end

  end
end
